﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using System.Xml;
using System.Diagnostics;
using System.Runtime.Remoting;
using System.Collections.ObjectModel;

namespace NService.Common
{
    /// <summary>
    /// 管理所有的服务
    /// </summary>
    public class ServiceManager : MarshalByRefObject
    {

        #region 单例模式
        private static ServiceManager _manager;
        private static object _lock = new object();
        /// <summary>
        /// 只能在主AppDomain中创建，子AppDomain需要获取AppDomain的代理
        /// </summary>
        public static ServiceManager Instance
        {
            get
            {
                if (AppDomain.CurrentDomain.IsDefaultAppDomain())
                {
                    //默认应用程序域中创建对象
                    if (_manager == null)
                    {
                        lock (_lock)
                        {
                            if (_manager == null)
                            {
                                _manager = new ServiceManager();
                                _manager.Init();
                                //AppDomain.CurrentDomain.is
                            }
                        }
                    }
                    return _manager;
                }
                else
                {
                    //获取代理
                    return AppDomain.CurrentDomain.GetData(DomainKey) as ServiceManager;
                }
            }
        }

        public readonly string ConfigFile;

        private ServiceManager()
        {
            string dir = AppDomain.CurrentDomain.BaseDirectory;
            ConfigFile = Path.Combine(dir, @"Data\services.xml");
        }
        #endregion

        #region 辅助方法
        private const string DomainKey = "ServiceManager";
        /// <summary>
        /// 绑定到程序域
        /// </summary>
        /// <param name="domain"></param>
        public void BindAppDomain(AppDomain domain)
        {
            if (domain.IsDefaultAppDomain())
                return;
            domain.SetData(DomainKey, this);
        }
        #endregion

        #region 元数据管理

        /// <summary>
        /// 所有服务的集合,键是服务的名称
        /// </summary>
        protected internal NServiceList InnerServices { get; set; }

        /// <summary>
        /// 在外部不能修改服务集合
        /// </summary>
        public ReadOnlyCollection<ServiceMeta> Services
        {
            get
            {
                return InnerServices.AsReadOnly();
            }
        }


        /// <summary>
        /// 初始化服务配置
        /// </summary>
        private void Init()
        {
            string dir = Path.GetDirectoryName(ConfigFile);
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
            if (!File.Exists(ConfigFile))
            {
                InnerServices = new NServiceList();
            }
            else
            {
                LoadConfig();
            }
        }

        /// <summary>
        /// 配置文件读写锁
        /// </summary>
        private object cfgLock = new object();
        /// <summary>
        /// 加载配置文件
        /// </summary>
        private void LoadConfig()
        {
            lock (cfgLock)
            {
                XmlSerializer ser = new XmlSerializer(typeof(NServiceList));
                XmlReader xr = XmlReader.Create(ConfigFile);
                this.InnerServices = ser.Deserialize(xr) as NServiceList;
            }
        }

        /// <summary>
        /// 保存配置文件
        /// </summary>
        private void SaveConfig()
        {
            lock (cfgLock)
            {
                XmlSerializer ser = new XmlSerializer(typeof(NServiceList));
                StreamWriter sw = new StreamWriter(ConfigFile);
                ser.Serialize(sw, InnerServices);
            }
        }

        /// <summary>
        /// 添加服务
        /// </summary>
        /// <param name="meta"></param>
        public ServiceManager AddService(ServiceMeta meta)
        {
            this.InnerServices.Add(meta);
            this.SaveConfig();
            return this;
        }

        /// <summary>
        /// 删除指定的服务
        /// </summary>
        /// <param name="name"></param>
        public ServiceManager DeleteService(string name)
        {
            //如果服务正在运行，先停止服务
            this.InnerServices.Remove(name);
            this.SaveConfig();
            return this;
        }

        /// <summary>
        /// 保存指定服务的参数配置信息
        /// </summary>
        /// <typeparam name="TParam"></typeparam>
        /// <param name="serviceName"></param>
        /// <param name="para"></param>
        /// <returns></returns>
        public ServiceManager SaveServiceParam<TParam>(string serviceName,TParam para) {
            return this;
        }

        /// <summary>
        /// 加载指定服务的参数配置信息
        /// </summary>
        /// <typeparam name="TParam"></typeparam>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        public TParam LoadServiceParam<TParam>(string serviceName) {
            TParam para = default(TParam);
            return para;
        }

        #endregion

        #region 运行管理

        /// <summary>
        /// 停止指定服务
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public ServiceManager StopService(string name)
        {

            return this;
        }
        /// <summary>
        /// 停止所有正在运行的服务
        /// </summary>
        /// <returns></returns>
        public ServiceManager StopAllService()
        {
            return this;
        }

        /// <summary>
        /// 启动指定服务
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public ServiceManager StartService(string name)
        {
            return this;
        }
        /// <summary>
        /// 启动所有没有禁用的服务
        /// </summary>
        /// <returns></returns>
        public ServiceManager StartAllSerivce()
        {
            return this;
        }
        #endregion

    }
}